﻿using System;
using System.Text;
using System.Text.RegularExpressions;
using FU.Capstones.IMS.Services.Common;
using FU.Capstones.IMS.Services.Common.DataContracts;
using FU.Capstones.IMS.Services.Common.Respondents;

namespace FU.Capstones.IMS.Services.Management
{
    public sealed class Validator
    {
        public static Feedback Validate<T>(T data) where T : class
        {
            if (data==null)
            {
                return new Feedback(string.Format(InventoryConstants.DataMissingMessage, typeof(T).Name), false);
            }
            return new Feedback(string.Empty,true);
        }

        public static Feedback Validate(Employee employee)
        {
            if (employee == null)
            {
                return new Feedback(InventoryConstants.Messages.NullData, false);
            }

            bool ok = true;
            StringBuilder stringBuilder = new StringBuilder();

            if (!ValidateUsername(employee.Username))
            {
                stringBuilder.AppendFormat(@"Tên đăng nhập: {0} \n", InventoryConstants.Messages.InvalidUsername);
                ok = false;
            }

            if (!ValidateEmail(employee.Email, true))
            {
                stringBuilder.AppendFormat(@"Thư điện tử: {0} \n", InventoryConstants.Messages.InvalidEmail);
                ok = false;
            }

            if (!ValidateICN(employee.IdentityCardNumber))
            {
                stringBuilder.AppendFormat(@"Số CMT: {0} \n", InventoryConstants.Messages.InvalidICN);
                ok = false;
            }
            
            if (!ValidateStringLength(employee.FullName, 1, 50, false))
            {
                stringBuilder.AppendFormat(@"Tên: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 50);
                ok = false;
            }

            if (!ValidateStringLength(employee.Address, 1, 4000, false))
            {
                stringBuilder.AppendFormat(@"Địa chỉ: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 4000);
                ok = false;
            }

            if (!ValidateGender(employee.Gender))
            {
                stringBuilder.AppendFormat(@"Giới tính: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidGender, "Nam", "Nữ");
                ok = false;
            }

            if (employee.AuthorizationCollection != null )
            {
                for (int outer = 0; outer < employee.AuthorizationCollection.Count - 1; outer++)
                {
                    int authorizationID = employee.AuthorizationCollection[outer];
                   
                    for (int inner = outer + 1; inner < employee.AuthorizationCollection.Count; inner++)
                    {
                        if (employee.AuthorizationCollection[inner] == authorizationID)
                        {
                            employee.AuthorizationCollection.RemoveAt(inner);
                            --outer;
                            --inner;
                        }
                    }
                }
            }

            return new Feedback(stringBuilder.ToString(), ok);
        }

        public static Feedback Validate(Product product)
        {
            if (product == null)
            {
                return new Feedback(InventoryConstants.Messages.NullData, false);
            }

            bool ok = true;
            StringBuilder stringBuilder = new StringBuilder();

            if (!ValidateStringLength(product.ProductName, 1, 50, false))
            {
                stringBuilder.AppendFormat(@"Tên: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 50);
                ok = false;
            }

            if (!ValidateStringLength(product.ProductCode, 1, 20, false))
            {
                stringBuilder.AppendFormat(@"Mã: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 20);
                ok = false;
            }

            if (!ValidateStringLength(product.Description, 1, 4000, false))
            {
                stringBuilder.AppendFormat(@"Miêu tả: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 4000);
                ok = false;
            }

            if (product.MaterialCollection != null)
            {
                for (int outer = 0; outer < product.MaterialCollection.Count-1; outer++)
                {
                    if (product.MaterialCollection [outer]== null)
                        product.MaterialCollection.RemoveAt(outer);
                }

                for (int outer = 0; outer < product.MaterialCollection.Count-1; outer++)
                {
                    Material material = product.MaterialCollection[outer];
                    
                    for (int inner = outer+1; inner < product.MaterialCollection.Count; inner++)
                    {
                        if (product.MaterialCollection[inner].MaterialID == material.MaterialID)
                        {
                            material.Quantity += product.MaterialCollection[inner].Quantity;
                            product.MaterialCollection.RemoveAt(inner);
                            --outer;
                            --inner;
                        }
                    }
                }
            }

            return new Feedback(stringBuilder.ToString(), ok);
        }

        public static Feedback Validate(Partner partner)
        {
            if (partner == null)
            {
                return new Feedback(InventoryConstants.Messages.NullData, false);
            }

            bool ok = true;
            StringBuilder stringBuilder = new StringBuilder();

            if (!ValidateStringLength(partner.CompanyName, 1, 50, false))
            {
                stringBuilder.AppendFormat(@"Tên công ty: {0}, ({1} - {2}) ", InventoryConstants.Messages.InvalidStringLength, 1, 50);
                ok = false;
            }

            if (!ValidateStringLength(partner.PartnerCode, 1, 20, false))
            {
                stringBuilder.AppendFormat(@"Mã: {0}, ({1} - {2}) ", InventoryConstants.Messages.InvalidStringLength, 1, 20);
                ok = false;
            }

            if (!ValidateStringLength(partner.Description, 1, 4000))
            {
                stringBuilder.AppendFormat(@"Miêu tả: {0}, ({1} - {2}) ", InventoryConstants.Messages.InvalidStringLength, 1, 4000);
                ok = false;
            }

            if (!ValidateStringLength(partner.OfficePhone, 1, 20, false))
            {
                stringBuilder.AppendFormat(@"Số điện thoại: {0}, ({1} - {2}) ", InventoryConstants.Messages.InvalidStringLength, 1, 20);
                ok = false;
            }

            return new Feedback(stringBuilder.ToString(), ok);
        }

        public static Feedback Validate(Material material)
        {
            if (material == null)
            {
                return new Feedback(InventoryConstants.Messages.NullData, false);
            }

            bool ok = true;
            StringBuilder stringBuilder = new StringBuilder();

            if (!ValidateStringLength(material.MaterialName, 1, 50, false))
            {
                stringBuilder.AppendFormat(@"Tên: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 50);
                ok = false;
            }

            if (!ValidateStringLength(material.MaterialCode, 1, 20, false))
            {
                stringBuilder.AppendFormat(@"Mã: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 20);
                ok = false;
            }

            if (!ValidateStringLength(material.Description, 1, 4000, false))
            {
                stringBuilder.AppendFormat(@"Miêu tả: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 4000);
                ok = false;
            }
            
            return new Feedback(stringBuilder.ToString(), ok);
        }

        public static Feedback Validate(EmploymentType eType)
        {
            if (eType == null)
            {
                return new Feedback(InventoryConstants.Messages.NullData, false);
            }

            eType.FullDescription = "For future";

            bool ok = true;
            StringBuilder stringBuilder = new StringBuilder();

            if (!ValidateStringLength(eType.EmploymentTypeName, 1, 50, false))
            {
                stringBuilder.AppendFormat(@"Tên: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 50);
                ok = false;
            }

            if (!ValidateStringLength(eType.EmploymentTypeCode, 1, 20, false))
            {
                stringBuilder.AppendFormat(@"Mã: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 20);
                ok = false;
            }

            if (!ValidateStringLength(eType.BriefDescription, 1, 4000, false))
            {
                stringBuilder.AppendFormat(@"Miêu tả: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 4000);
                ok = false;
            }

            return new Feedback(stringBuilder.ToString(), ok);
        }

        public static Feedback Validate(Role role)
        {
            if (role == null)
            {
                return new Feedback(InventoryConstants.Messages.NullData, false);
            }

            role.FullDescription = "For future";

            bool ok = true;
            StringBuilder stringBuilder = new StringBuilder();

            if (!ValidateStringLength(role.RoleName, 1, 50, false))
            {
                stringBuilder.AppendFormat(@"Tên: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 50);
                ok = false;
            }

            if (!ValidateStringLength(role.RoleCode, 1, 20, false))
            {
                stringBuilder.AppendFormat(@"Mã: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 20);
                ok = false;
            }

            if (!ValidateStringLength(role.BriefDescription, 1, 4000, false))
            {
                stringBuilder.AppendFormat(@"Miêu tả: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 4000);
                ok = false;
            }

            return new Feedback(stringBuilder.ToString(), ok);
        }

        public static Feedback Validate(Contact contact)
        {
            if (contact == null)
            {
                return new Feedback(InventoryConstants.Messages.NullData, false);
            }

            bool ok = true;
            StringBuilder stringBuilder = new StringBuilder();

            if (!ValidateStringLength(contact.FullName, 1, 50, false))
            {
                stringBuilder.AppendFormat(@"Tên: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 50);
                ok = false;
            }

            if (!ValidateStringLength(contact.MobilePhone, 1, 20, false))
            {
                stringBuilder.AppendFormat(@"Sô điện thoại: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 20);
                ok = false;
            }

            return new Feedback(stringBuilder.ToString(), ok);
        }

        public static Feedback Validate(Warehouse warehouse)
        {
            if (warehouse == null)
            {
                return new Feedback(InventoryConstants.Messages.NullData, false);
            }

            bool ok = true;
            StringBuilder stringBuilder = new StringBuilder();

            if (!ValidateStringLength(warehouse.WarehouseName, 1, 50, false))
            {
                stringBuilder.AppendFormat(@"Tên: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 50);
                ok = false;
            }

            if (!ValidateStringLength(warehouse.Description, 1, 4000, false))
            {
                stringBuilder.AppendFormat(@"Miêu tả: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 4000);
                ok = false;
            }

            if (!ValidateStringLength(warehouse.Address, 1, 150, false))
            {
                stringBuilder.AppendFormat(@"Địa chỉ: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 150);
                ok = false;
            }

            if (!ValidateStringLength(warehouse.OfficePhone, 1, 20, false))
            {
                stringBuilder.AppendFormat(@"Số điện thoại: {0}, ({1} - {2})\n", InventoryConstants.Messages.InvalidStringLength, 1, 20);
                ok = false;
            }

            if (warehouse.Manager == null || warehouse.Manager.EmployeeID == 0)
            {
                stringBuilder.AppendFormat(@"Người quản lí: {0})\n", "Lack of warehouse manager");
                ok = false;
            }
            return new Feedback(stringBuilder.ToString(), ok);
        }

        public static Feedback ValidateStringEmpty(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return new Feedback("This string is empty", false);
            }
            else
            {
                return new Feedback(str, true);
            }
        }

        public static Feedback ValidateStringLength50(string str)
        {
            if (str.Length >=50)
            {
                return new Feedback("This string is more than 50 words", false);
            }
            else
            {
                return new Feedback(str, true);
            }
        }

        public  static  Feedback ValidateStringLength10 (string str)
        {
            if (str.Length >=10)
            {
                return new Feedback("This string is more than 50 words",false);
            }
            else
            {
                return new Feedback(str,true);
            }
        }

        public static Feedback ValidateEmail (string email)
        {
            string emailPattern = @"\b[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}\b";

            Regex emailReg = new Regex(emailPattern);
            if (emailReg.IsMatch(email))
            {
                return new Feedback(email,true);
            }
            else
            {
                return new Feedback("This email address is not valid",false);
            }
        }

        public static Feedback ValidateDateFromAndTo (DateTime dateFrom,DateTime dateTo)
        {
            if (dateFrom.CompareTo(dateTo) > 0 )
            {
                return new Feedback("DateFrom must be smaller than DateTo",false);
            }
            else
            {
                return new Feedback(Convert.ToString(dateFrom.CompareTo(dateTo)), true);
            }
        }

        private static bool ValidateStringLength(string  stringToValidate, int minLength, int maxLength, bool acceptNullOrEmpty = true)
        {
            if (!string.IsNullOrEmpty(stringToValidate))
            {
                return stringToValidate.Length >= minLength && stringToValidate.Length <= maxLength;
            }
            return acceptNullOrEmpty;
        }

        private static bool ValidateEmail(string emailToValidate, bool acceptNullOrEmpty)
        {
            if (!string.IsNullOrEmpty(emailToValidate))
            {
                Regex regex = new Regex(InventoryConstants.EmailRegex);
                return regex.IsMatch(emailToValidate);
            }
            return acceptNullOrEmpty;

        }

        private static bool ValidateICN(string icnToValidate)
        {
            if (!string.IsNullOrEmpty(icnToValidate))
            {
                Regex regex = new Regex(InventoryConstants.ICNRegex);
                return regex.IsMatch(icnToValidate);
            }
            return false;

        }

        private static bool ValidateUsername(string usernameToValidate)
        {
            if (usernameToValidate != null)
            {
                if (ValidateStringLength(usernameToValidate, 4, 50))
                {
                    Regex regex = new Regex(InventoryConstants.UsernameRegex);
                    return regex.IsMatch(usernameToValidate);
                }
                return true;
            }
            return false;
        }

        private static bool ValidateGender(string genderToValidate)
        {
            return string.Compare(genderToValidate, "Nam") == 0 || string.Compare(genderToValidate, "Nữ") == 0;
        }
    }
}